#include "smart_rga.hpp"

int SmartRga::init(cfg_t src_cfg, cfg_t dst_cfg)
{
    int ret;
    
    ret = config_src(src_cfg);
    if (ret) {
        return -1;
    }
    ret = config_dst(dst_cfg);
    if (ret) {
        return -1;
    }

    return 0;

FAILED_RESIZE:
    deinit();
    return ret;
}

int SmartRga::config_src(cfg_t cfg)
{
    if (-1 != m_src_handle) {
        releasebuffer_handle(m_src_handle);
        m_src_handle = -1;
    }

    memset(&m_src_rect, 0, sizeof(m_src_rect));
    memset(&m_src, 0, sizeof(m_src));
    
    m_src_cfg = cfg;

    log_debug("rga src w/h/f/b: %d/%d/0x%X/%p.", 
					m_src_cfg.width, m_src_cfg.height, m_src_cfg.format, m_src_cfg.buffer);

    m_src_handle = importbuffer_virtualaddr(m_src_cfg.buffer, m_src_cfg.width, m_src_cfg.height, m_src_cfg.format);
    if (m_src_handle <= 0) {
        log_error("Failed to import virtualaddr for src channel!\n");
        return -1;
    }

    m_src = wrapbuffer_handle(m_src_handle, m_src_cfg.width, m_src_cfg.height, m_src_cfg.format);
    if(m_src.width == 0) {
        log_error("%s, %s", __FUNCTION__, imStrError());
        deinit();
        return -1;
    }

    return 0;
}

int SmartRga::config_dst(cfg_t cfg)
{
    if (-1 != m_dst_handle) {
        releasebuffer_handle(m_dst_handle);
        m_dst_handle = -1;
    }

    memset(&m_dst_rect, 0, sizeof(m_dst_rect));
    memset(&m_dst, 0, sizeof(m_dst));

    m_dst_cfg = cfg;
    log_debug("rga dst w/h/f/b: %d/%d/0x%X/%p.", 
					m_dst_cfg.width, m_dst_cfg.height, m_dst_cfg.format, m_dst_cfg.buffer);

    m_dst_handle = importbuffer_virtualaddr(m_dst_cfg.buffer, m_dst_cfg.width, m_dst_cfg.height, m_dst_cfg.format);
    if (m_dst_handle <= 0) {
        log_error("Failed to import virtualaddr for dst channel!\n");
        return -1;
    }

    m_dst = wrapbuffer_handle(m_dst_handle, m_dst_cfg.width, m_dst_cfg.height, m_dst_cfg.format);
    if(m_dst.width == 0) {
        log_error("%s, %s", __FUNCTION__, imStrError());
        deinit();
        return -1;
    }

    return 0;
}

int SmartRga::deinit()
{
    if (-1 != m_src_handle) {
        releasebuffer_handle(m_src_handle);
        m_src_handle = -1;
    }
    if (-1 != m_dst_handle) {
        releasebuffer_handle(m_dst_handle);
        m_dst_handle = -1;
    }
    return 0;
}

int SmartRga::resize()
{
    int ret = imcheck(m_src, m_dst, m_src_rect, m_dst_rect);
    if (IM_STATUS_NOERROR != ret) {
        log_error("%d, resize check error! %s\n", imStrError((IM_STATUS)ret));
        return -1;
    }

    IM_STATUS STATUS = imresize(m_src, m_dst);
    log_debug("rga imresize: %s.", imStrError(STATUS));
    if (STATUS != IM_STATUS_SUCCESS) {
        log_error("rga imresize failed: %s.", imStrError(STATUS));
        return -1;
    }

    return 0;
}

int SmartRga::cvtcolor()
{
    int ret = imcheck(m_src, m_dst, m_src_rect, m_dst_rect);
    if (IM_STATUS_NOERROR != ret) {
        log_error("%d, resize check error! %s\n", imStrError((IM_STATUS)ret));
        return -1;
    }

    IM_STATUS STATUS = imcvtcolor(m_src, m_dst, m_src_cfg.format, m_dst_cfg.format);
    log_debug("rga imcvtcolor: %s.", imStrError(STATUS));
    if (STATUS != IM_STATUS_SUCCESS) {
        log_error("rga imresize failed: %s.", imStrError(STATUS));
        return -1;
    }

    return 0;
}

int SmartRga::get_image_size(int width, int height, RgaSURF_FORMAT format) {
    return width * height * get_bpp_from_format(format);
}
